﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using S3.DataModel;
using S3.Common;

namespace S3.Biz
{
    public class DailyTimingEntryManager : CommonManager
    {

        #region Constants

        //string msgRawChangeDesk = "- [" + string.Format(Constants.Format_Date_Time, DateTime.Now) + "] " + "Đã chuyển từ {0} sang {1}.";
        private static string finish = DailyEntryStatusValue.Text[DailyEntryStatus.Finished];
        private static string playing = DailyEntryStatusValue.Text[DailyEntryStatus.Playing];
        private static string switched = DailyEntryStatusValue.Text[DailyEntryStatus.Switched];

        #endregion

        /// <summary>
        /// Tinh tien theo block
        /// </summary>
        /// <param name="playedMinutes"></param>
        /// <param name="kindOfMachine"></param>
        /// <returns></returns>
        #region CalcGameMoneyByBlock
        public decimal CalcGameMoneyByBlock(decimal playedMinutes, string kindOfMachine, int? firstBlockMinutes, decimal? firstBlockUnitPrice, int? nextBlockMinutes, decimal? nextBlockUnitPrice)
        {
            decimal totalMoney = 0;
            decimal firstBlockMoney = 0;
            decimal nextBlockMoney = 0;
            decimal firstBlock = 0;
            decimal nextBlock = 0;

            try
            {
                if (firstBlockUnitPrice == null || nextBlockUnitPrice == null)
                {
                    using (TimeBlockUnitPriceManager manager = new TimeBlockUnitPriceManager())
                    {

                        var priceEntry = manager.GetOne(kindOfMachine);
                        if (priceEntry == null) return 0;

                        firstBlock = priceEntry.FirstBlockTime.Value;
                        nextBlock = priceEntry.NextBlockTime.Value;

                        firstBlockMoney = priceEntry.FirstBlockUnitPrice.Value;
                        nextBlockMoney = priceEntry.NextBlockUnitPrice.Value;
                    }
                }
                else
                {
                    firstBlockMoney = firstBlockUnitPrice.Value;
                    nextBlockMoney = nextBlockUnitPrice.Value;

                    firstBlock = firstBlockMinutes.Value;
                    nextBlock = nextBlockMinutes.Value;
                }


                if (playedMinutes <= firstBlock)
                {
                    totalMoney = firstBlockMoney;
                }
                else
                {
                    var numberOfNextBlock = (playedMinutes - firstBlock) / nextBlock;
                    //var blocks = playedMinutes / nextBlock;
                    //var floor = Math.Round(blocks,0);//Floor, not Ceiling

                    totalMoney = firstBlockMoney + Convert.ToDecimal(numberOfNextBlock * nextBlockMoney);

                }

                return totalMoney;

            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("CalcGameMoneyByBlock::CalcGameMoneyByBlock::" + playedMinutes + "::" + kindOfMachine, ex, true);
                }
            }

            return totalMoney;
        }
        #endregion

        /// <summary>
        /// Save entry to SQL and return ID of this record.
        /// </summary>
        /// <param name="dailyEntry"></param>
        #region Add
        public long Add(DailyTimingEntry dailyEntry)
        {
            try
            {
                //Add new
                if (dailyEntry.DailyTimingEntryID == 0)
                {

                    _entities.AddToDailyTimingEntries(dailyEntry);
                }

                //Submit change                
                _entities.SaveChanges();
                //ActionLogger.LogAction(ActionType.StartMachine, Constants.StaffName, DateTime.Now, new string[] { dailyEntry.TimingServiceName });
            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("DailyTimingEntryManager::Add::" + dailyEntry.TimingServiceName, ex, true);
                }
            }

            return dailyEntry.DailyTimingEntryID;

        }
        #endregion


        /// <summary>
        /// Delete any entries
        /// </summary>
        /// <param name="dailyEntry"></param>
        #region Delete
        public void Delete(string strIDs)
        {
            try
            {
                //Add new
                if (!string.IsNullOrEmpty(strIDs))
                {
                    var listIDs = strIDs.Split(';');
                    foreach (var strId in listIDs)
                    {
                        long id;
                        if (!string.IsNullOrEmpty(strId) && long.TryParse(strId, out id))
                        {
                            var dailyEntry = _entities.DailyTimingEntries.FirstOrDefault(a => a.DailyTimingEntryID == id);
                            _entities.DeleteObject(dailyEntry);

                            var serviceEntry = _entities.DailyItemEntries.Where(a => a.DailyTimingEntryID == dailyEntry.DailyTimingEntryID).ToList();


                            serviceEntry.ForEach(_entities.DeleteObject);

                        }
                    }

                    //Submit change
                    _entities.SaveChanges();
                }

            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("DailyTimingEntryManager::Delete::", ex, true);
                }
            }

        }
        #endregion


        /// <summary>
        /// Get One instance account
        /// </summary>
        /// <param name="shortName"></param>
        /// <param name="isDeleted"></param>
        /// <returns></returns>
        #region GetOne
        public DailyTimingEntry GetOne(string deskName)
        {
            //Check parameter
            if (string.IsNullOrEmpty(deskName)) return null;

            try
            {
                //get thong tin cua ban theo ten ban
                return _entities.DailyTimingEntries.FirstOrDefault(a => a.TimingServiceName.ToLower() == deskName.ToLower());

            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("DailyTimingEntryManager::GetOne::" + deskName, ex, true);
                }
            }

            return null;
        }

        /// <summary>
        /// get thong tin cua ban dang co trang thai "Dang choi"
        /// </summary>
        /// <param name="deskName"></param>
        /// <returns></returns>
        public DailyTimingEntry GetOnePlaying(string deskName)
        {
            //Check parameter
            if (string.IsNullOrEmpty(deskName)) return null;

            try
            {
                //get thong tin cua ban dang co trang thai "Dang choi"

                return _entities.DailyTimingEntries.FirstOrDefault(a => a.TimingServiceName.ToLower() == deskName.ToLower() && a.Status.ToLower() == playing);

            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("DailyTimingEntryManager::GetOnePlaying::" + deskName, ex, true);
                }
            }

            return null;
        }

        #endregion

        #region IsPlaying
        /// <summary>
        /// Check is playing or not
        /// </summary>
        /// <param name="deskName"></param>
        /// <returns></returns>
        public bool IsPlaying(string deskName)
        {
            var playingDesks = GetPlayingDesks().Where(a => a.TimingServiceName.Equals(deskName, StringComparison.OrdinalIgnoreCase));
            return playingDesks != null && playingDesks.Count() > 0 ? true : false;
        }
        #endregion

        /// <summary>
        /// get thong tin cua tat ca ban ghi da ket thuc
        /// </summary>        
        /// <returns></returns>
        #region GetFinishedDesks
        public IQueryable<DailyTimingEntry> GetFinishedDesks()
        {
            try
            {
                //get thong tin cua ban dang co trang thai "Da ket thuc"

                return _entities.DailyTimingEntries.Where(a => a.Status.ToLower() == finish);

            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("DailyTimingEntryManager::GetFinishedDesks::", ex, true);
                }
            }

            return null;
        }
        #endregion

        /// <summary>
        /// get thong tin cua tat ca ban ghi da ket thuc
        /// </summary>        
        /// <returns></returns>
        #region GetFinishedBySession
        public List<ExtendDailyEntry> GetFinishedBySession(ref decimal totalMoney)
        {
            var result = new List<ExtendDailyEntry>();
            try
            {
                //get thong tin cua ban dang co trang thai "Da ket thuc"
                var rawList = GetFinishedDesks().Where(a => a.SessionBy == null || a.SessionBy == string.Empty);

                var customList = from o in rawList
                                 group o by o.TimingServiceName into g
                                 select new { TimingServiceName = g.Key, Money = g.Sum(o => o.Amount) };//select new { TimingServiceName = g.Key, Money = g.Sum(o => o.Amount - o.Amount + o.Paid) };

                //select new { TimingServiceName = g.Key, GameMoney = g.Sum(o=>o.Amount - o.Amount + o.Paid), TotalMoney = g.Sum(o => o.Amount + o.Paid) };

                foreach (var item in customList)
                {
                    totalMoney = totalMoney + item.Money;

                    var subList = rawList.Where(a => a.TimingServiceName.ToLower() == item.TimingServiceName.ToLower()).Select(a => new { a.StartTime, a.EndTime });
                    decimal totalTime = 0;
                    foreach (var i in subList)
                    {
                        totalTime = totalTime + Convert.ToDecimal(i.EndTime.Value.Subtract(i.StartTime).TotalMinutes);
                    }

                    ExtendDailyEntry n = new ExtendDailyEntry()
                    {
                        TimingServiceName = item.TimingServiceName,
                        TotalTime = totalTime < 1 ? "1" : Utils.StringFormatMoney(totalTime),
                        TotalMoney = Utils.StringFormatMoney(item.Money)
                    };

                    result.Add(n);
                }

            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("DailyTimingEntryManager::GetFinishedBySession::", ex, true);
                }
            }

            return result;
        }
        #endregion

        /// <summary>
        /// get thong tin cua tat ca ban ghi da tra tien nhung chua ban giao: Session = (null || Empty)
        /// </summary>        
        /// <returns></returns>
        #region GetNotFinishSession
        public IQueryable<DailyTimingEntry> GetNotFinishSession()
        {
            try
            {
                return GetFinishedDesks().Where(a => a.SessionBy == null || a.SessionBy == string.Empty);

            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("DailyTimingEntryManager::GetNotFinishSession::", ex, true);
                }
            }

            return null;
        }
        #endregion

        /// <summary>
        /// Ket thuc phien lam viec - Ban giao
        /// </summary>
        /// <param name="staffName"></param>
        #region FinishSession
        public void FinishSession(string staffName)
        {
            var listGame = GetFinishedDesks().Where(a => a.SessionBy == null || a.SessionBy == string.Empty);
            foreach (var item in listGame)
            {
                item.SessionBy = staffName;
                item.ModifiedBy = staffName;
                item.ModifiedDate = DateTime.Now;
            }

            _entities.SaveChanges();

            using (DailyItemEntryManager manager = new DailyItemEntryManager())
            {
                manager.FinishSession(staffName);
            }


        }
        #endregion

        /// <summary>
        /// get thong tin cua ban dang co trang thai "Dang choi"
        /// </summary>        
        /// <returns></returns>
        #region GetPlayingDesks
        public IQueryable<DailyTimingEntry> GetPlayingDesks()
        {
            try
            {
                //get thong tin cua ban dang co trang thai "Dang choi"                
                //return PsmEntities.DailyTimingEntries;
                return _entities.DailyTimingEntries.Where(a => a.Status.ToLower() == playing);


            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("DailyTimingEntryManager::GetPlayingDesks::", ex, true);
                }
            }

            return null;
        }
        #endregion

        #region ReportGameMoneyResult
        /// <summary>
        /// Bao cao tien game
        /// </summary>
        /// <param name="currentDate"></param>
        /// <param name="reportType"></param>
        /// <param name="totalMoney"></param>
        /// <returns></returns>
        public List<ExtendDailyEntry> ReportGameMoneyResult(DateTime currentDate, ReportType reportType, ref decimal gameMoney, ref decimal totalMoney)
        {
            List<ExtendDailyEntry> result = new List<ExtendDailyEntry>();
            try
            {
                //Get finished records
                var list = _entities.DailyTimingEntries.Where(a => a.Status == finish).ToList();

                if (list != null || list.Count() > 0)
                {

                    switch (reportType)
                    {
                        case ReportType.Daily:
                            list = list.Where(a => a.EndTime.Value.Day == currentDate.Day && a.EndTime.Value.Month == currentDate.Month && a.EndTime.Value.Year == currentDate.Year).ToList();
                            break;
                        case ReportType.Monthly:
                            list = list.Where(a => a.EndTime.Value.Month == currentDate.Month && a.EndTime.Value.Year == currentDate.Year).ToList();
                            break;

                    }

                    var customList = from o in list
                                     group o by o.TimingServiceName into g
                                     select new { TimingServiceName = g.Key, GameMoney = g.Sum(o => o.Amount), TotalMoney = g.Sum(o => o.Amount) };//select new { TimingServiceName = g.Key, GameMoney = g.Sum(o => o.Amount - o.Amount + o.Paid), TotalMoney = g.Sum(o => o.Amount + o.Paid) };


                    foreach (var item in customList)
                    {
                        gameMoney = gameMoney + item.GameMoney;
                        totalMoney = totalMoney + item.TotalMoney;

                        var subList = list.Where(a => a.TimingServiceName.ToLower() == item.TimingServiceName.ToLower()).Select(a => new { a.StartTime, a.EndTime });
                        decimal totalTime = 0;
                        foreach (var i in subList)
                        {
                            totalTime = totalTime + Convert.ToDecimal(i.EndTime.Value.Subtract(i.StartTime).TotalMinutes);
                        }

                        ExtendDailyEntry reportGameMoney = new ExtendDailyEntry()
                        {
                            TimingServiceName = item.TimingServiceName,
                            TotalTime = totalTime < 1 ? "1" : Utils.StringFormatMoney(totalTime),
                            GameMoney = Utils.StringFormatMoney(item.GameMoney),
                            TotalMoney = Utils.StringFormatMoney(item.TotalMoney)
                        };

                        result.Add(reportGameMoney);
                    }
                }
            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("DailyTimingEntryManager::ReportGameMoneyResult::", ex, true);
                }
            }

            return result;
        }
        #endregion

        /// <summary>
        /// Get thong tin cua ban hien tai, bao gom ban ghi o trang thai "da chuyen" va "dang choi" cua ban hien tai
        /// </summary>
        /// <param name="deskName"></param>
        /// <returns></returns>
        #region GetWatingFinishByDesk
        public IQueryable<DailyTimingEntry> GetWatingFinishEntriesByDesk(string invoiceNo)
        {
            //Check parameter
            if (string.IsNullOrEmpty(invoiceNo)) return null;

            try
            {
                //get thong tin cua ban dang co trang thai "Dang choi"
                //return PsmEntities.DailyTimingEntry.Where(a => a.TimingServiceName.ToLower() == deskName.ToLower() && (a.Status.ToLower() == DailyEntryStatusValue.Text[DailyEntryStatus.Playing].ToLower() || a.Status.ToLower() == DailyEntryStatusValue.Text[DailyEntryStatus.Switched].ToLower()));
                var playing = DailyEntryStatusValue.Text[DailyEntryStatus.Playing];
                return _entities.DailyTimingEntries.Where(a => a.InvoiceNo == invoiceNo && (a.Status.ToLower() == playing || a.Status.ToLower() == switched));

            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("DailyTimingEntryManager::GetWatingFinishByDesk::" + invoiceNo, ex, true);
                }
            }

            return null;
        }
        #endregion

        #region CalTotalMoneyByDesk
        public decimal CalTotalMoneyByDesk(string invoiceNo)
        {
            decimal money = 0;

            return CalTotalMoneyByDesk(invoiceNo, ref money, ref money);
        }

        public decimal CalTotalMoneyByDesk(string invoiceNo, ref decimal gameMoney, ref decimal totalMoney)
        {
            decimal decGameMoney = 0;

            decimal decTotal = 0;

            try
            {
                //Get cac ban ghi "chua hoan thanh" cua ban hien tai
                var waitingProcessList = GetWatingFinishEntriesByDesk(invoiceNo).ToList();

                using (DailyTimingEntryManager block = new DailyTimingEntryManager())
                {
                    //var subMinutes1 = from o in waitingProcessList
                    //group o by o.Type into g
                    //select new { DailyTimingEntryID = g.Key, SubTotal = g.Sum(o => o.Amount) };
                    var kindOfMachines = Utils.KindOfMachinesList();
                    foreach (var machine in kindOfMachines)
                    {
                        //var strKindMachine = machine.ToLower();
                        var strKindMachine = machine;
                        //Tinh tien cac ban ghi cung kieu may
                        var entryList = waitingProcessList.Where(a => a.Type == strKindMachine);
                        //So tien cua kieu may hien tai
                        decimal playedMinutes = 0;

                        foreach (var dailyEntry in entryList)
                        {
                            if (!dailyEntry.EndTime.HasValue)
                            {
                                playedMinutes = playedMinutes + Convert.ToDecimal(DateTime.Now.Subtract(dailyEntry.StartTime).TotalMinutes);
                            }
                            else
                            {
                                playedMinutes = playedMinutes + Convert.ToDecimal(dailyEntry.EndTime.Value.Subtract(dailyEntry.StartTime).TotalMinutes);
                            }

                            //Tien duoc tra ho                    
                            //decPaidMoney = decPaidMoney + dailyEntry.Paid;
                        }

                        if (playedMinutes > 0)
                        {
                            decGameMoney = decGameMoney + block.CalcGameMoneyByBlock(playedMinutes, machine, null, null, null, null);
                        }
                    }
                }




                decTotal = decGameMoney;

                totalMoney = decTotal;
            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("DailyTimingEntryManager::CalTotalMoneyByDesk::" + invoiceNo, ex, true);
                }
            }

            return decTotal;
        }
        #endregion


        /// <summary>
        /// Dung choi, tinh tien
        /// </summary>
        /// <param name="deskName"></param>
        /// <param name="totalServiceFee"></param>
        /// <param name="totalFund"></param>
        /// <param name="endTime"></param>
        #region StopPlaying
        public void StopPlaying(string deskName, decimal totalServiceFee, decimal totalFund, DateTime endTime)
        {
            try
            {
                //BeginTransaction();

                var entries = GetWatingFinishEntriesByDesk(deskName);
                long deskStopingID = 0;

                foreach (var entry in entries)
                {
                    if (entry != null)
                    {
                        if (entry.Status == playing)
                        {
                            //Them tien dich vu vao ban ghi DailyTimingEntry
                            entry.Amount = totalServiceFee;

                            //Gio ket thuc
                            entry.EndTime = endTime;

                            //Tong tien phai tra = tong tien - (da tra * (-1))
                            entry.Amount = totalFund;// +entry.Paid;

                            //Reset paid                            
                            //entry.Paid = 0;

                            //ID
                            if (deskStopingID == 0)
                            {
                                deskStopingID = entry.DailyTimingEntryID;
                            }

                            //Update Remark
                            using (DailyItemEntryManager dailyAdditionalItemEntryManager = new DailyItemEntryManager())
                            {
                                var unpaidServices = dailyAdditionalItemEntryManager.GetUnpaidByDesk(deskName);
                                StringBuilder str = new StringBuilder();
                                foreach (var item in unpaidServices)
                                {
                                    if (item.Quantity > 0)
                                    {
                                        str.Append(item.Quantity);
                                        str.Append(" ");
                                        str.Append(item.ItemName);
                                        str.Append(", ");

                                        string[] param = { str.ToString() };

                                        entry.Notes += Utils.FormatNotesMessage(param, NotesType.TimingServiceUsedServices);
                                    }
                                }

                            }
                        }

                        entry.ModifiedBy = Constants.StaffName;
                        entry.ModifiedDate = DateTime.Now;

                        //Chuyen trang thai ban ghi Daily entry sang "Chưa bắt đầu"
                        entry.Status = finish;
                    }
                }

                //Chuyen trang thai cac Dich vu sang "Đã trả"
                using (DailyItemEntryManager dailyAdditionalItemEntryManager = new DailyItemEntryManager())
                {
                    dailyAdditionalItemEntryManager.StopPlaying(deskName, deskStopingID);
                }


                //Submit change
                _entities.SaveChanges();
                //ActionLogger.LogAction(ActionType.StopMachine, Constants.StaffName, DateTime.Now, new string[] { deskName });

                //CommitTransaction();
            }
            catch (Exception ex)
            {
                //RollbackTransaction();

                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("DailyTimingEntryManager::StopPlaying::" + deskName, ex, true);
                }
            }
        }
        #endregion

        /// <summary>
        /// Tim loai may da choi lan gan day nhat
        /// Tinh huong: Ban A co 2 loai may PS2 va PS3, khi may nghi choi, lan sau muon bat nhanh, he thong tu dong goi y nguoi quan ly may da choi gan day nhat
        /// Nhiem vu: Tim loai may ma khach hang da choi gan day cua ban hien tai.
        /// </summary>
        /// <param name="deskName"></param>
        /// <returns></returns>
        #region FindKindOfMachineNearestPlayed
        public string FindKindOfMachineNearestPlayed(string deskName)
        {
            var result = "";
            //Check parameter
            if (string.IsNullOrEmpty(deskName)) return result;

            try
            {
                //get thong tin Type gan day nhat cua ban
                var listResult = _entities.DailyTimingEntries.Where(a => a.TimingServiceName.ToLower() == deskName.ToLower()).Select(a => new { a.Type, a.ModifiedDate }).OrderByDescending(a => a.ModifiedDate);
                if (listResult.Count() > 0)
                {
                    return listResult.FirstOrDefault().Type;
                }

            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("DailyTimingEntryManager::FindKindOfMachineNearestPlayed::" + deskName, ex, true);
                }
            }

            return result;
        }
        #endregion


        /// <summary>
        /// Save entry to SQL
        /// </summary>
        /// <param name="dailyEntry"></param>
        #region ChangeKindOfMachine
        public void ChangeKindOfMachine(string deskName, string newKindOfMachine, bool isFinishLastPlaying)
        {
            try
            {
                //Search this desk
                var entry = GetOnePlaying(deskName);
                var oldType = new StringBuilder();
                if (entry != null)
                {
                    if (isFinishLastPlaying)
                    {
                        //string msgRaw = "- [" + string.Format(Constants.Format_Date_Time, DateTime.Now) + "] " + "Đã chuyển từ {0} sang {1}.";
                        //string msg = string.Format(msgRaw, entry.Type, newKindOfMachine);
                        string[] param = { entry.Type, newKindOfMachine };

                        //Ket thuc ban ghi hien tai
                        entry.EndTime = DateTime.Now;
                        entry.Notes += Utils.FormatNotesMessage(param, NotesType.TimingServiceChangeType);// string.IsNullOrEmpty(entry.Notes) ? msg : entry.Notes + System.Environment.NewLine + msg;
                        //entry.Status = DailyEntryStatusValue.Text[DailyEntryStatus.Switched];
                        entry.Status = switched;
                        oldType.Append(entry.Type);
                        //Tao ban ghi moi                        
                        DailyTimingEntry newEntry = new DailyTimingEntry()
                        {
                            TimingServiceName = entry.TimingServiceName,
                            StartTime = DateTime.Now,
                            Type = newKindOfMachine,
                            StaffName = Constants.StaffName,
                            Notes = entry.Notes,
                            //Status = DailyEntryStatusValue.Text[DailyEntryStatus.Playing],
                            Status = playing,
                            ModifiedDate = DateTime.Now,
                            ModifiedBy = Constants.StaffName
                        };

                        _entities.AddToDailyTimingEntries(newEntry);
                    }
                    else
                    {
                        entry.Type = newKindOfMachine;
                    }

                    //Chot tien cua may truoc                    
                    entry.ModifiedBy = Constants.StaffName;
                    entry.ModifiedDate = DateTime.Now;

                }

                //Submit change
                _entities.SaveChanges();
                //ActionLogger.LogAction(ActionType.ChangeType, Constants.StaffName, DateTime.Now, new string[] { deskName, oldType.ToString(), newKindOfMachine, isFinishLastPlaying ? "Có" : "Không" });
            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("DailyTimingEntryManager::ChangeKindOfMachine::" + deskName, ex, true);
                }
            }

        }
        #endregion

        /// <summary>
        /// cap nhat ghi chu
        /// </summary>
        /// <param name="deskName"></param>
        /// <param name="remark"></param>
        #region UpdateRemark
        public void AppendNotes(string deskName, string remark)
        {
            UpdateNotes(deskName, remark, false);
        }
        #endregion

        /// <summary>
        /// Save entry to SQL
        /// </summary>
        /// <param name="dailyEntry"></param>
        #region UpdateNotes
        public void UpdateNotes(string deskName, string remark, bool isReplace)
        {
            try
            {
                //Search this desk
                var entry = GetOnePlaying(deskName);
                if (entry != null)
                {
                    if (isReplace)
                    {
                        entry.Notes = remark;
                    }
                    else
                    {
                        entry.Notes += remark;
                    }

                    entry.ModifiedBy = Constants.StaffName;
                    entry.ModifiedDate = DateTime.Now;
                }

                //Submit change
                _entities.SaveChanges();

            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("DailyTimingEntryManager::UpdateRemark::" + deskName, ex, true);
                }
            }

        }
        #endregion

        #region SwitchDesk
        /// <summary>
        /// Chuyen ban
        /// </summary>
        /// <param name="dailyEntry"></param>
        public void SwitchDesk(string fromDesk, string fromKindOfMachine, string fromKindOfMachineWantToPlay, bool fromStopCurrentPlaying, string desDesk, string desKindOfMachine, string desKindOfMachineWantToPlay, bool desStopCurrentPlaying)
        {
            try
            {
                //var transaction = BeginTransaction();

                //Chuyen may hien tai
                SwitchDeskOneWay(fromDesk, fromKindOfMachine, desDesk, fromKindOfMachineWantToPlay, fromStopCurrentPlaying);

                //Check playing or not?                 
                //Neu may dich o trang thai "Dang choi" thi phai chuyen het du lieu sang may nguon.
                if (IsPlaying(desDesk))
                {
                    SwitchDeskOneWay(desDesk, desKindOfMachine, fromDesk, desKindOfMachineWantToPlay, desStopCurrentPlaying);
                }

                //Chuyen do goi them cua ban hien tai sang ban dich
                using (DailyItemEntryManager dailyAdditionalItemEntryManager = new DailyItemEntryManager())
                {
                    dailyAdditionalItemEntryManager.SwitchDesk(fromDesk, desDesk);
                }

                //Submit change
                _entities.SaveChanges();

                //CommitTransaction(transaction);

            }
            catch (Exception ex)
            {
                //RollbackTransaction(transaction);

                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("DailyTimingEntryManager::SwitchDesk::" + fromDesk + "|" + fromDesk, ex, true);
                }
            }

        }

        /// <summary>
        /// Chuyen ban`
        /// </summary>
        /// <param name="currentDesk"></param>
        /// <param name="fromMachine"></param>
        /// <param name="destinationDesk"></param>
        /// <param name="toMachine"></param>
        /// <param name="isBreakNew">True: chuyen 2 ban cho nhau | False: Chuyen tu ban dang choi sang ban trong'</param>
        private void SwitchDeskOneWay(string currentDesk, string fromMachine, string destinationDesk, string toMachine, bool isBreakNew)
        {
            try
            {
                string[] param = { currentDesk, destinationDesk };

                if (isBreakNew && fromMachine.ToLower() != toMachine.ToLower())
                {
                    //Search current desk
                    var currentPlayingDeskRecordList = GetWatingFinishEntriesByDesk(currentDesk);
                    DailyTimingEntry cloneEntry = null;
                    foreach (var entry in currentPlayingDeskRecordList)
                    {
                        //Ket thuc ban ghi hien tai Switched
                        if (entry != null)
                        {
                            entry.TimingServiceName = destinationDesk;
                            entry.ModifiedBy = Constants.StaffName;
                            entry.ModifiedDate = DateTime.Now;

                            if (entry.Status.ToLower() == DailyEntryStatusValue.Text[DailyEntryStatus.Playing].ToLower())
                            {
                                entry.EndTime = DateTime.Now;

                                //Clone this entry
                                cloneEntry = entry;
                            }

                            entry.Status = DailyEntryStatusValue.Text[DailyEntryStatus.Switched];

                        }
                    }



                    //Them 1 ban ghi giong ban ghi hien tai
                    if (cloneEntry != null)
                    {
                        DailyTimingEntry newEntry = new DailyTimingEntry()
                        {
                            TimingServiceName = cloneEntry.TimingServiceName,
                            StartTime = DateTime.Now,
                            Type = toMachine,
                            StaffName = Constants.StaffName,
                            Status = DailyEntryStatusValue.Text[DailyEntryStatus.Playing],
                            ModifiedDate = DateTime.Now,
                            ModifiedBy = Constants.StaffName,
                            EndTime = null,
                            //Notes = string.IsNullOrEmpty(cloneEntry.Notes) ? string.Format(msgRawChangeDesk, currentDesk, destinationDesk) : cloneEntry.Notes + System.Environment.NewLine + string.Format(msgRawChangeDesk, currentDesk, destinationDesk),
                        };
                        StringBuilder strNotes = new StringBuilder();
                        strNotes.AppendLine(cloneEntry.Notes);
                        strNotes.Append(Utils.FormatNotesMessage(param, NotesType.TimingServiceChangeDesk));
                        newEntry.Notes = strNotes.Replace("\r\n\r\n", "\r\n").ToString();

                        _entities.AddToDailyTimingEntries(newEntry);
                    }
                }
                else
                {
                    //Tim tat ca ban ghi chua ket thuc cua may hien tai va doi ten sang may dich
                    var currentPlayingDeskRecordList = GetWatingFinishEntriesByDesk(currentDesk);

                    foreach (var entry in currentPlayingDeskRecordList)
                    {
                        entry.TimingServiceName = destinationDesk;
                        entry.ModifiedBy = Constants.StaffName;
                        entry.ModifiedDate = DateTime.Now;

                        if (entry.Status.ToLower() == DailyEntryStatusValue.Text[DailyEntryStatus.Playing].ToLower())
                        {
                            entry.Type = toMachine;
                            entry.Notes += Utils.FormatNotesMessage(param, NotesType.TimingServiceChangeDesk);// string.IsNullOrEmpty(entry.Notes) ? string.Format(msgRawChangeDesk, currentDesk, destinationDesk) : entry.Notes + System.Environment.NewLine + string.Format(msgRawChangeDesk, currentDesk, destinationDesk);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("DailyTimingEntryManager::SwitchDeskOneWay::", ex, true);
                }
            }

        }

        #endregion

        #region TransferMoney
        /// <summary>
        /// Chuyen tien sang ban khac
        /// </summary>
        /// <param name="dailyEntry"></param>
        public void TransferMoney(string currentDesk, string destinationDesk, decimal money)
        {
            try
            {
                string strMoney = Utils.StringFormatMoney(money);
                string[] paramReceiveMoney = { strMoney, currentDesk };
                string[] paramTransferMoney = { strMoney, destinationDesk };
                //string msgRawDaNhan = "- [" + string.Format(Constants.Format_Date_Time, DateTime.Now) + "] " + "Đã nhận {0} đồng từ {1}.";
                //string msgRawDaChuyen = "- [" + string.Format(Constants.Format_Date_Time, DateTime.Now) + "] " + "Đã chuyển {0} đồng sang {1}.";

                //Update destination machine
                var entry = GetOnePlaying(destinationDesk);
                if (entry != null)
                {
                    //entry.Paid = entry.Paid + money;
                    entry.Notes += Utils.FormatNotesMessage(paramReceiveMoney, NotesType.TimingServiceReceivedMoney);// string.IsNullOrEmpty(entry.Notes) ? string.Format(msgRawDaNhan, strMoney, currentDesk) : entry.Notes + System.Environment.NewLine + string.Format(msgRawDaNhan, strMoney, currentDesk);
                    entry.ModifiedBy = Constants.StaffName;
                    entry.ModifiedDate = DateTime.Now;
                }

                //update current machine

                var dailyEntryCurrentDesk = GetOnePlaying(currentDesk);

                if (dailyEntryCurrentDesk != null)
                {
                    //dailyEntryCurrentDesk.Paid = dailyEntryCurrentDesk.Paid + (money * (-1));
                    dailyEntryCurrentDesk.Notes += Utils.FormatNotesMessage(paramTransferMoney, NotesType.TimingServiceTransferedMoney);// string.IsNullOrEmpty(dailyEntryCurrentDesk.Notes) ? string.Format(msgRawDaChuyen, strMoney, destinationDesk) : entry.Notes + System.Environment.NewLine + string.Format(msgRawDaChuyen, strMoney, destinationDesk);
                    dailyEntryCurrentDesk.ModifiedBy = Constants.StaffName;
                    dailyEntryCurrentDesk.ModifiedDate = DateTime.Now;
                }

                //Submit change
                _entities.SaveChanges();

            }
            catch (Exception ex)
            {
                using (var exception = new SSDLoggingHandler())
                {
                    exception.BizException("DailyTimingEntryManager::TransferMoney::" + currentDesk + "|" + destinationDesk, ex, true);
                }
            }

        }
        #endregion

    }
}
